---
type: tutorial
title: レイアウトを組み合わせ、両方の長所を活かす
description: |-
  「初めてのAstroブログ」チュートリアル -
  ブログ記事をフォーマットするレイアウトに、基本のページレイアウトを追加する
i18nReady: true
---
import Blanks from '~/components/tutorial/Blanks.astro';
import Box from '~/components/tutorial/Box.astro';
import Checklist from '~/components/Checklist.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import { Steps } from '@astrojs/starlight/components';

各ブログ記事にレイアウトを追加したところで、記事の見た目をサイトの他のページに近づけてみましょう！

<PreCheck>
  - メインのページレイアウトの中にブログ記事レイアウトを入れ子にする
</PreCheck>

## 2つのレイアウトを入れ子にする

ページ全体のレイアウトを定義するための`BaseLayout.astro`はすでにあります。

一方`MarkdownPostLayout.astro`は、`title`や`date`など、ブログ記事共通のプロパティに対応するテンプレートを提供しますが、ブログ記事ページはサイトの他のページとは異なる見た目になってしまっています。**レイアウトを入れ子にする**ことで、ブログ記事の見た目をサイトの他のページに合わせてみましょう。

<Steps>
1. `src/layouts/MarkdownPostLayout.astro`に`BaseLayout.astro`をインポートし、テンプレートのコンテンツ全体を包みます。`pageTitle`propを渡すのを忘れないでください。

    ```astro title="src/layouts/MarkdownPostLayout.astro" ins={2,5,12}
    ---
    import BaseLayout from './BaseLayout.astro';
    const { frontmatter } = Astro.props;
    ---
    <BaseLayout pageTitle={frontmatter.title}>
      <h1>{frontmatter.title}</h1>
      <p>{frontmatter.pubDate.toString().slice(0,10)}</p>
      <p><em>{frontmatter.description}</em></p>
      <p>著者: {frontmatter.author}</p>
      <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
      <slot />
    </BaseLayout>
    ```

2. `http://localhost:4321/posts/post-1`をブラウザのプレビューで確認します。コンテンツは現在、以下によってレンダリングされています。

    - スタイル、ナビゲーションリンク、ソーシャルフッターを含む**メインのページレイアウト**
    - 記事の説明文、日付、タイトル、画像などのフロントマタープロパティを含む**ブログ記事レイアウト**
    - この記事に表示されるテキストのみを含む**個別のブログ記事のMarkdownコンテンツ**

3. ページタイトルが各レイアウトで1回ずつ、合計2回表示されていることに注意してください。

    `MarkdownPostLayout.astro`からページタイトルを表示する行を削除します。

    ```astro title="src/layouts/MarkdownPostLayout.astro" del={2}
    <BaseLayout pageTitle={frontmatter.title}>
      <h1>{frontmatter.title}</h1>
      <p>{frontmatter.pubDate.toString().slice(0,10)}</p>
      <p><em>{frontmatter.description}</em></p>
      <p>著者: {frontmatter.author}</p>
      <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
      <slot />
    </BaseLayout>
    ```

4. `http://localhost:4321/posts/post-1`をブラウザのプレビューで再度確認し、上で削除した行が表示されなくなり、タイトルが1回だけ表示されていることを確認します。コンテンツが重複しないよう、必要に応じて他の調整をおこなってください。
</Steps>

  以下のことを確認してください。

    - 各ブログ記事は同じページテンプレートを表示しており、欠けているコンテンツはない。(ブログ記事のコンテンツが欠落している場合は、記事のフロントマタープロパティを確認してください。)

    - ページにコンテンツが重複していない。(2回レンダリングされているコンテンツがある場合は、`MarkdownPostLayout.astro`から削除してください。)

    なお、好みに合わせてページテンプレートをカスタマイズしても構いません。




<Box icon="question-mark">

### 確認テスト

1. あるレイアウトを別のレイアウトの中に入れ子にし、個々のパーツを組み合わせることを可能にするのは以下のどれですか？

    <MultipleChoice>
      <Option>
        継続的デプロイ
      </Option>
      <Option>
        レスポンシブデザイン
      </Option>
      <Option isCorrect>
        コンポーネントベースの設計
      </Option>
    </MultipleChoice>

2. Markdownページを含むプロジェクトでは複数のレイアウトが特に有用です。これに当てはまるのは以下のどれですか？

    <MultipleChoice>
      <Option isCorrect>
        ブログ
      </Option>
      <Option>
        ダッシュボード
      </Option>
      <Option>
        チャットアプリ
      </Option>
    </MultipleChoice>

3. 各ページ共通のテンプレートは以下のどれですか？

    <MultipleChoice>
      <Option>
        `index.astro`
      </Option>
      <Option isCorrect>
        `BaseLayout.astro`
      </Option>
      <Option>
        `post-1.md`
      </Option>
    </MultipleChoice>
</Box>

<Box icon="check-list">

## チェックリスト

<Checklist>
- [ ] 重複した要素に注意しながら、レイアウトを入れ子にすることができる。
</Checklist>
</Box>

### 参考

- [Astroにおけるレイアウトの入れ子](/ja/basics/layouts/#レイアウトの入れ子)
